package saobracaj;

import java.util.ArrayList;
import timer.Timer;


public class Raskrsnica extends Thread {

	public static final long zakasnjenje = 1500;
	public static final int zelenoP = 30;
	public static final int zelenoPesaci = 15;
	public static final int zelenoL = 30;
	public static final int zelenoD = 30;
	
	

	private ArrayList<Automobil> severP;
	public Integer kseverP;
	private ArrayList<Automobil> severL;
	public Integer kseverL;
	private ArrayList<Automobil> severD;
	public Integer kseverD;
	private ArrayList<Automobil> jugP;
	public Integer kjugP;
	private ArrayList<Automobil> jugL;
	public Integer kjugL;
	private ArrayList<Automobil> jugD;
	public Integer kjugD;
	private ArrayList<Automobil> istokP;
	public Integer kistokP;
	private ArrayList<Automobil> istokL;
	public Integer kistokL;
	private ArrayList<Automobil> istokD;
	public Integer kistokD;
	private ArrayList<Automobil> zapadP;
	public Integer kzapadP;
	private ArrayList<Automobil> zapadL;
	public Integer kzapadL;
	private ArrayList<Automobil> zapadD;
	public Integer kzapadD;
	
	public ArrayList<Pesak> psever1;
	public ArrayList<Pesak> psever2;
	public ArrayList<Pesak> pjug1;
	public ArrayList<Pesak> pjug2;
	public ArrayList<Pesak> pistok1;
	public ArrayList<Pesak> pistok2;
	public ArrayList<Pesak> pzapad1;
	public ArrayList<Pesak> pzapad2;
	
	public boolean severLsenz = false;
	public boolean severPsenz = false;
	public boolean severDsenz = false;
	public boolean zapadLsenz = false;
	public boolean zapadPsenz = false;
	public boolean zapadDsenz = false;
	public boolean jugLsenz = false;
	public boolean jugPsenz = false;
	public boolean jugDsenz = false;
	public boolean istokLsenz = false;
	public boolean istokPsenz = false;
	public boolean istokDsenz = false;
	
	
	private Semafor[] severS;
	private Semafor[] jugS;
	private Semafor[] istokS;
	private Semafor[] zapadS;
	
	public Semafor severPes, jugPes, istokPes, zapadPes;
	
	private Timer tajmerS, tajmerI;//tajmerJ, , //tajmerZ;
	
	private Object sync = new Object();
	private Object syncSever = new Object();
	private Object syncJug = new Object();
	private Object syncIstok = new Object();
	private Object syncZapad = new Object();
	private Object pSever = new Object();
	private Object pJug = new Object();
	private Object pZapad = new Object();
	private Object pIstok = new Object();

	public int tNorth;
	public int tSouth;
	public int tWest;
	public int tEast;
	
	
	
	private boolean treptanje = false;
        
   //     private RaskrsnicaGUI raskGUI = RaskrsnicaGUI.dohvatiRaskrsnicu();
	
	
	public Raskrsnica() {
		
		tNorth = 0;
		tSouth = 0;
		tWest = 0;
		tEast = 0;
		
		severP = new ArrayList<Automobil>();
		severL = new ArrayList<Automobil>();
		severD = new ArrayList<Automobil>();
		jugP = new ArrayList<Automobil>();
		jugL = new ArrayList<Automobil>();
		jugD = new ArrayList<Automobil>();
		istokP = new ArrayList<Automobil>();
		istokL = new ArrayList<Automobil>();
		istokD = new ArrayList<Automobil>();
		zapadP = new ArrayList<Automobil>();
		zapadL = new ArrayList<Automobil>();
		zapadD = new ArrayList<Automobil>();

		kseverP = new Integer(0);
		kseverL = new Integer(0);
		kseverD = new Integer(0);
		kistokP = new Integer(0);
		kistokL = new Integer(0);
		kistokD = new Integer(0);
		kjugP   = new Integer(0);
		kjugL = new Integer(0);
		kjugD = new Integer(0);
		kzapadP = new Integer(0);
		kzapadD = new Integer(0);
		kzapadL = new Integer(0);
		
		severS = new Semafor[3];
		jugS = new Semafor[3];
		istokS = new Semafor[3];
		zapadS = new Semafor[3];
		psever1 = new ArrayList<Pesak>();
		psever2 = new ArrayList<Pesak>();
		pjug1 = new ArrayList<Pesak>();
		pjug2 = new ArrayList<Pesak>();
		pistok1 = new ArrayList<Pesak>();
		pistok2 = new ArrayList<Pesak>();
		pzapad1 = new ArrayList<Pesak>();
		pzapad2 = new ArrayList<Pesak>();
		
		
		for (int i=0; i<3; i++) {
			severS[i] = new Semafor(this, 'a', 11 + i);
			severS[i].postaviZuto();
			jugS[i] = new Semafor(this, 'a', 33 - i);
			jugS[i].postaviZuto();
			istokS[i] = new Semafor(this, 'a', 23 - i);
			istokS[i].postaviZuto();
			zapadS[i] = new Semafor(this, 'a', 43 - i);
			zapadS[i].postaviZuto();			
		}	//TODO mozda da trepce ovde dok se ne startuje
		
		severPes = new Semafor(this, 'b', 1);
		jugPes = new Semafor(this, 'b', 3);
		istokPes = new Semafor(this, 'b', 2);
		zapadPes = new Semafor(this, 'b', 4);
		
	
		
		//TODO videti zbog levo i desno
		tajmerS = new Timer(this, zelenoL+zelenoP, severS[2], severS[1], severS[0], jugS[0], jugS[1], jugS[2], zapadPes, istokPes);
		//tajmerJ = new Timer(zelenoL+zelenoP, jugS[0], jugS[1], jugS[2], istokPes);
		tajmerI = new Timer(this, zelenoL+zelenoP, istokS[0], istokS[1], istokS[2], zapadS[0], zapadS[1], zapadS[2], severPes, jugPes);
		//tajmerZ = new Timer(zelenoL+zelenoP, zapadS[0], zapadS[1], zapadS[2], jugPes);
		
		tajmerS.setSusedni(tajmerI);
		//tajmerJ.setSusedni(tajmerI);
		tajmerI.setSusedni(tajmerS);
		//tajmerZ.setSusedni(tajmerS);
				
		tajmerS.start();
	//	tajmerJ.start();
		tajmerI.start();
		//tajmerZ.start();
		
		//start();
	}
	
	public void startuj() {
		synchronized (sync) {
			for (int i=0; i<3; i++) {
				severS[i].initSemafor();
				jugS[i].initSemafor();
				istokS[i].initSemafor();
				zapadS[i].initSemafor();			
			}	//TODO mozda da trepce ovde dok se ne startuje
			
			severPes.initSemafor();
			jugPes.initSemafor();
			istokPes.initSemafor();
			zapadPes.initSemafor();
			
			treptanje = false;
		}
		
		//RaskrsnicaGUI.dohvatiRaskrsnicu().repaint();
		/*synchronized (sync) {
			sync.notify();
		}*/
		//treptanje = false;
		
	}

	public void dodajAuto(Automobil s, int pravac) {
		System.out.println("lfdllf");
		if (pravac < 20)
			synchronized (syncSever) {
				switch (pravac) {
				case 11:
					//if ((severS[0].dohvatiSvetlo() == 1) && !severS[0].crvenoZuto())
					//severDsenz = true;
					severD.add(s);
					System.out.println("dodat");
					break;
				case 12:
					//if ((severS[1].dohvatiSvetlo() == 1))// && !severS[1].crvenoZuto())
					//severPsenz = true;
					severP.add(s);
					System.out.println("dodat");
					break;
				case 13:
					//if ((severS[2].dohvatiSvetlo() == 1) && !severS[2].crvenoZuto())
					//severLsenz = true;
					severL.add(s);
					break;
				}
			}
		else if (pravac < 30)
			synchronized (syncIstok) {
				switch (pravac) {
				case 21:
					//istokDsenz = true;
					istokD.add(s);
					break;
				case 22:
					//istokPsenz = true;
					istokP.add(s);
					break;
				case 23:
					//istokLsenz = true;
					istokL.add(s);
					break;
				}
			}
		else if (pravac < 40)
			synchronized (syncJug) {
				switch (pravac) {
				case 31:
					//jugDsenz = true;
					jugD.add(s);
					break;
				case 32:
					//jugPsenz = true;
					jugP.add(s);
					break;
				case 33:
					///jugLsenz = true;
					jugL.add(s);
					break;
				}
			}
		else
			synchronized (syncZapad) {
				switch (pravac) {
				case 41:
					//zapadDsenz = true;
					zapadD.add(s);
					break;
				case 42:
					//zapadPsenz = true;
					zapadP.add(s);
					break;
				case 43:
					//zapadLsenz = true;
					zapadL.add(s);
					break;
				}
			}
	
	}
	
	public void izbaciAuto(Automobil s, int pravac) {
		//TODO izbacivanje za svaki smer
		switch (pravac) {
		case 0:
			synchronized (severP) {
				severP.remove(s);
			}
			break;
		case 1:
			synchronized (jugP) {
				jugP.remove(s);
			}
			break;
		case 2:
			synchronized (istokP) {
				istokP.remove(s);
			}
			break;
		case 3:
			synchronized (zapadP) {
				zapadP.remove(s);
			}
			break;
		}
	}
	
	public void dodajPesaka(Pesak p, int pravac){
		switch(pravac) {
		case 0: synchronized (pSever) {
				psever1.add(p);
				}
				break;
		case 1: synchronized (pSever) {
				psever2.add(p);
				}
				break;
		case 2: synchronized (pIstok) {
				pistok1.add(p);
				}
				break;
		case 3: synchronized (pIstok) {
				pistok2.add(p);
				}
				break;
		case 4: synchronized (pJug) {
				pjug1.add(p);
				}
				break;
		case 5: synchronized (pJug) {
				pjug2.add(p);
				}
				break;
		case 6: synchronized (pZapad) {
				pzapad1.add(p);
				}
				break;
		case 7: synchronized (pZapad) {
				pzapad2.add(p);
				}
				break;
		}
	}
	
	public void izbaciPesaka(Pesak p, int pravac){
		
		switch(pravac) {
		case 0: synchronized (pSever) {
				psever1.remove(p);
				}
				break;
		case 1: synchronized (pSever) {
				psever2.remove(p);
				}
				break;
		case 2: synchronized (pIstok) {
				pistok1.remove(p);
				}
				break;
		case 3: synchronized (pIstok) {
				pistok2.remove(p);
				}
				break;
		case 4: synchronized (pJug) {
				pjug1.remove(p);
				}
				break;
		case 5: synchronized (pJug) {
				pjug2.remove(p);
				}
				break;
		case 6: synchronized (pZapad) {
				pzapad1.remove(p);
				}
				break;
		case 7: synchronized (pZapad) {
				pzapad2.remove(p);
				}
				break;
		}
		
	}
	
	
	
	public void run() {
		synchronized (sync) {
			if (!treptanje)
			try {
				System.out.println("dcs");
				sync.wait();
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//treptanje = true;
		RaskrsnicaGUI raskGUI = RaskrsnicaGUI.dohvatiRaskrsnicu();
		while (treptanje) {
			for (int i=0; i<3; i++) {
				severS[i].postaviIskljuceno();
				jugS[i].postaviIskljuceno();
				istokS[i].postaviIskljuceno();
				zapadS[i].postaviIskljuceno();
				
			}
			raskGUI.repaint();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			for (int i=0; i<3; i++) {
				severS[i].postaviZuto();
				jugS[i].postaviZuto();
				istokS[i].postaviZuto();
				zapadS[i].postaviZuto();
				
			}
			raskGUI.repaint();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for (int i=0; i<3; i++) {
			//severS[i] = new Semafor('a');
			severS[i].postaviCrveno();
			//jugS[i] = new Semafor('a');
			jugS[i].postaviCrveno();
			//istokS[i] = new Semafor('a');
			istokS[i].postaviCrveno();
			//zapadS[i] = new Semafor('a');
			zapadS[i].postaviCrveno();
		}
		severPes.postaviCrveno();
		jugPes.postaviCrveno();
		istokPes.postaviCrveno();
		zapadPes.postaviCrveno();
		raskGUI.repaint();
		try {
			Thread.sleep(zakasnjenje);
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
		tajmerS.signal();
		//tajmerJ.signal();
		try {
			tajmerS.join();
			//tajmerJ.join();
			tajmerI.join();
			//tajmerZ.join();
		}
		catch(InterruptedException e) {
			e.printStackTrace();
		}
		//tajmerI.signal();
		//tajmerZ.signal();
		
	}

	
	public ArrayList<Automobil> getSeverP() {
		return severP;
	}

	public void setSeverP(ArrayList<Automobil> severP) {
		this.severP = severP;
	}

	public ArrayList<Automobil> getJugP() {
		return jugP;
	}

	

	public ArrayList<Automobil> getIstokP() {
		return istokP;
	}



	public ArrayList<Automobil> getZapadP() {
		return zapadP;
	}

	

	public ArrayList<Automobil> getSeverL() {
		return severL;
	}

	public void setSeverL(ArrayList<Automobil> severL) {
		this.severL = severL;
	}

	public ArrayList<Automobil> getSeverD() {
		return severD;
	}

	public void setSeverD(ArrayList<Automobil> severD) {
		this.severD = severD;
	}

	public ArrayList<Automobil> getJugL() {
		return jugL;
	}

	public void setJugL(ArrayList<Automobil> jugL) {
		this.jugL = jugL;
	}

	public ArrayList<Automobil> getJugD() {
		return jugD;
	}

	public void setJugD(ArrayList<Automobil> jugD) {
		this.jugD = jugD;
	}

	public ArrayList<Automobil> getIstokL() {
		return istokL;
	}

	public void setIstokL(ArrayList<Automobil> istokL) {
		this.istokL = istokL;
	}

	public ArrayList<Automobil> getIstokD() {
		return istokD;
	}

	public void setIstokD(ArrayList<Automobil> istokD) {
		this.istokD = istokD;
	}

	public ArrayList<Automobil> getZapadL() {
		return zapadL;
	}

	public void setZapadL(ArrayList<Automobil> zapadL) {
		this.zapadL = zapadL;
	}

	public void setZapadP(ArrayList<Automobil> zapadP) {
		this.zapadP = zapadP;
	}
	

	public ArrayList<Automobil> getZapadD() {
		return zapadD;
	}

	public void setZapadD(ArrayList<Automobil> zapadD) {
		this.zapadD = zapadD;
	}

	public void setJugP(ArrayList<Automobil> jugP) {
		this.jugP = jugP;
	}

	public void setIstokP(ArrayList<Automobil> istokP) {
		this.istokP = istokP;
	}

	public Semafor[] getSeverS() {
		return severS;
	}

	public void setSeverS(Semafor[] severS) {
		this.severS = severS;
	}

	public Semafor[] getJugS() {
		return jugS;
	}

	public void setJugS(Semafor[] jugS) {
		this.jugS = jugS;
	}

	public Semafor[] getIstokS() {
		return istokS;
	}

	public void setIstokS(Semafor[] istokS) {
		this.istokS = istokS;
	}

	public Semafor[] getZapadS() {
		return zapadS;
	}

	public void setZapadS(Semafor[] zapadS) {
		this.zapadS = zapadS;
	}
	
	
	

	public Timer getTajmerS() {
		return tajmerS;
	}

	public void setTajmerS(Timer tajmerS) {
		this.tajmerS = tajmerS;
	}

	/*public Timer getTajmerJ() {
		return tajmerJ;
	}

	public void setTajmerJ(Timer tajmerJ) {
		this.tajmerJ = tajmerJ;
	}*/

	public Timer getTajmerI() {
		return tajmerI;
	}

	public void setTajmerI(Timer tajmerI) {
		this.tajmerI = tajmerI;
	}

	/*public Timer getTajmerZ() {
		return tajmerZ;
	}

	public void setTajmerZ(Timer tajmerZ) {
		this.tajmerZ = tajmerZ;
	}*/

	public static int getZelenop() {
		return zelenoP;
	}

	public static int getZelenol() {
		return zelenoL;
	}

	public static int getZelenod() {
		return zelenoD;
	}

	public Semafor getSeverPes() {
		return severPes;
	}

	public Semafor getJugPes() {
		return jugPes;
	}

	public Semafor getIstokPes() {
		return istokPes;
	}

	public Semafor getZapadPes() {
		return zapadPes;
	}

	public void pocni() {
		synchronized (sync) {
			treptanje = true;
			System.out.println("dsddsa");
			sync.notify();
		}
		
	}
	
	public ArrayList<Pesak> getPsever1() {
		return psever1;
	}

	public void setPsever1(ArrayList<Pesak> psever1) {
		this.psever1 = psever1;
	}

	public ArrayList<Pesak> getPsever2() {
		return psever2;
	}

	public void setPsever2(ArrayList<Pesak> psever2) {
		this.psever2 = psever2;
	}

	public ArrayList<Pesak> getPjug1() {
		return pjug1;
	}

	public void setPjug1(ArrayList<Pesak> pjug1) {
		this.pjug1 = pjug1;
	}

	public ArrayList<Pesak> getPjug2() {
		return pjug2;
	}

	public void setPjug2(ArrayList<Pesak> pjug2) {
		this.pjug2 = pjug2;
	}

	public ArrayList<Pesak> getPistok1() {
		return pistok1;
	}

	public void setPistok1(ArrayList<Pesak> pistok1) {
		this.pistok1 = pistok1;
	}

	public ArrayList<Pesak> getPistok2() {
		return pistok2;
	}

	public void setPistok2(ArrayList<Pesak> pistok2) {
		this.pistok2 = pistok2;
	}

	public ArrayList<Pesak> getPzapad1() {
		return pzapad1;
	}

	public void setPzapad1(ArrayList<Pesak> pzapad1) {
		this.pzapad1 = pzapad1;
	}

	public ArrayList<Pesak> getPzapad2() {
		return pzapad2;
	}

	public void setPzapad2(ArrayList<Pesak> pzapad2) {
		this.pzapad2 = pzapad2;
	}

	public Object getSyncSever() {
		return syncSever;
	}

	public Object getSyncJug() {
		return syncJug;
	}

	public Object getSyncIstok() {
		return syncIstok;
	}

	public Object getSyncZapad() {
		return syncZapad;
	}
	
	
	
	
}
